package dao

import (
	"encoding/json"
	"github.com/gin-gonic/gin"
	"gorm.io/datatypes"
	"gorm.io/gorm"
	"web_api_gin/dto"
	"web_api_gin/entity"
)

var SysUser = SysUserDao{}

type SysUserDao struct {
}

//通过邮箱查找用户数据
func (d *SysUserDao) FindByEmail(ctx *gin.Context, email string) (*entity.SysUsers, error) {
	var user *entity.SysUsers
	result := DB(ctx).Where(&entity.SysUsers{Email: email}).Limit(1).Find(&user)
	return user, result.Error
}

//通过邮箱查找用户数据
func (d *SysUserDao) FindById(ctx *gin.Context, id uint32) (*entity.SysUsers, error) {
	var user *entity.SysUsers
	result := DB(ctx).First(&user, id)
	return user, result.Error
}

// 获取用户分页列表
func (d *SysUserDao) GetPageList(ctx *gin.Context, searchParams *dto.SysUserGetListReq) ([]*entity.SysUsers, int64, error) {
	var list []*entity.SysUsers
	var total int64
	tx := DB(ctx).Model(&entity.SysUsers{})
	if searchParams.Name != "" {
		tx = tx.Where("name like ?", "%"+searchParams.Name+"%")
	}
	if searchParams.Email != "" {
		tx = tx.Where("email like ?", "%"+searchParams.Email+"%")
	}
	if searchParams.Status == 1 { //激活

	} else if searchParams.Status == 2 { //禁用
		tx = tx.Unscoped().Where("deleted_at IS NOT NULL")
	} else {
		tx = tx.Unscoped()
	}
	err := tx.Count(&total).Order("id DESC").Limit(int(searchParams.PageSize)).Offset(int((searchParams.PageNo - 1) * searchParams.PageSize)).Find(&list).Error
	//转换用户角色json数据
	for _, res := range list {
		//清空密码数据
		res.Password = ""
	}
	return list, total, err
}

// 更新用户信息
func (d SysUserDao) UpdateUser(ctx *gin.Context, userId uint32, data *entity.SysUsers) error {
	var user *entity.SysUsers
	if err := DB(ctx).First(&user, userId).Error; err != nil {
		return err
	}
	return DB(ctx).Model(&user).Updates(data).Error
}

// 保存用户数据
func (d *SysUserDao) SaveUser(ctx *gin.Context, data *entity.SysUsers) error {
	return DB(ctx).Transaction(func(tx *gorm.DB) error {
		if data.Geographic == nil {
			data.Geographic = datatypes.JSON("{}")
		}
		//更新用户表
		if data.Id != 0 {
			if err := tx.Unscoped().Updates(data).Error; err != nil {
				return err
			}
		} else {
			if err := tx.Create(&data).Error; err != nil {
				return nil
			}
		}
		//删除旧的用户角色关系数据
		if err := tx.Unscoped().Where("user_id = ?", data.Id).Delete(&entity.SysRoleUser{}).Error; err != nil {
			return err
		}
		//更新用户角色关联表
		var roleUserList []entity.SysRoleUser
		var userRoleList []dto.SysUserRoleIdVal
		json.Unmarshal(data.RoleIds, &userRoleList)
		if len(userRoleList) > 0 {
			for _, val := range userRoleList {
				roleUserList = append(roleUserList, entity.SysRoleUser{
					RoleId: val.Value,
					UserId: data.Id,
				})
			}
			//批量添加关联数据
			if err := tx.Create(roleUserList).Error; err != nil {
				return err
			}
		}
		//更新用户角色缓存
		if data.RoleIds != nil {
			SysRole.GetUserRoleListCache(ctx, data, true)
		}

		return nil
	})
}

//禁用用户
func (d *SysUserDao) DisableUser(ctx *gin.Context, userIds []uint32) error {
	return DB(ctx).Transaction(func(tx *gorm.DB) error {
		//禁用即删除用户数据
		if err := tx.Delete(&entity.SysUsers{}, userIds).Error; err != nil {
			return err
		}
		//删除用户关联角色数据
		return nil
	})
}

//激活用户
func (d *SysUserDao) EnableUser(ctx *gin.Context, userIds []uint32) error {
	return DB(ctx).Transaction(func(tx *gorm.DB) error {
		//恢复用户
		if err := tx.Model(&entity.SysUsers{}).Select("deleted_at").Unscoped().Where("id in ?", userIds).Updates(map[string]interface{}{"deleted_at": nil}).Error; err != nil {
			return err
		}
		return nil
	})
}
